package com.cryptooj.project.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cryptooj.project.annotation.AuthCheck;
import com.cryptooj.project.common.BaseResponse;
import com.cryptooj.project.common.DeleteRequest;
import com.cryptooj.project.common.ErrorCode;
import com.cryptooj.project.common.ResultUtils;
import com.cryptooj.project.constant.UserConstant;
import com.cryptooj.project.exception.BusinessException;
import com.cryptooj.project.model.dto.question.*;
import com.cryptooj.project.model.dto.questionsubmit.QuestionSubmitAddRequest;
import com.cryptooj.project.model.dto.questionsubmit.QuestionSubmitQueryRequest;
import com.cryptooj.project.model.entity.Question;
import com.cryptooj.project.model.entity.QuestionSubmit;
import com.cryptooj.project.model.entity.User;
import com.cryptooj.project.model.vo.QuestionSubmitVO;
import com.cryptooj.project.model.vo.QuestionVO;
import com.cryptooj.project.service.QuestionService;
import com.cryptooj.project.service.QuestionSubmitService;
import com.cryptooj.project.service.UserService;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 *  题目controller
 * */
@RestController
@Slf4j
@RequestMapping("/question")
public class QuestionController {
    @Resource
    private QuestionService questionService;

    @Resource
    private UserService userService;

    @Resource
    private QuestionSubmitService questionSubmitService;

    private static final Gson GSON = new Gson(); // Json类型转换辅助

    /**
     *  增删改查
     * */
    @PostMapping("/add")
    public BaseResponse<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest, HttpServletRequest request) {
        if(questionAddRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(questionAddRequest, question);
        // 单独处理无法直接转换的变量
        List<String> tags = questionAddRequest.getTags();
        if(tags != null){
            question.setTags(GSON.toJson(tags));
        }
        List<JudgeCase> judgeCase = questionAddRequest.getJudgeCase();
        if(judgeCase != null){
            question.setJudgeCase(GSON.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = questionAddRequest.getJudgeConfig();
        if (judgeConfig != null) {
            question.setJudgeConfig(GSON.toJson(judgeConfig));
        }
        questionService.validQuestion(question,true);
        User loginUser = userService.getLoginUser(request);
        question.setUserId(loginUser.getId());
        question.setFavourNum(0);
        question.setThumbNum(0);
        boolean save = questionService.save(question);
        if(!save){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        long id = question.getId();
        return ResultUtils.success(id);
    }

    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request){
        if(deleteRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Long oldQuestionId = deleteRequest.getId();
        Question oldQuestion = questionService.getById(oldQuestionId);
        if(oldQuestion == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        if(!oldQuestion.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = questionService.removeById(oldQuestionId);
        return ResultUtils.success(b);
    }

    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateQuestion(@RequestBody QuestionUpdateRequest questionUpdateRequest){
        if(questionUpdateRequest == null || questionUpdateRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(questionUpdateRequest,question);
        // 单独处理无法直接转换的变量
        List<String> tags = questionUpdateRequest.getTags();
        if(tags != null){
            question.setTags(GSON.toJson(tags));
        }
        List<JudgeCase> judgeCase = questionUpdateRequest.getJudgeCase();
        if(judgeCase != null){
            question.setJudgeCase(GSON.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = questionUpdateRequest.getJudgeConfig();
        if(judgeConfig != null){
            question.setJudgeConfig(GSON.toJson(judgeConfig));
        }
        questionService.validQuestion(question,false);
        long oldQuestionId = questionUpdateRequest.getId();
        Question oldQuestion = questionService.getById(oldQuestionId);
        if(oldQuestion == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        boolean b = questionService.updateById(question);
        return ResultUtils.success(b);
    }

    /**
     *  查：本人或管理员能够获取非脱敏前的User对象
     * */
    @GetMapping("/get")
    public BaseResponse<Question> getQuestionById(long id, HttpServletRequest request){
        if(id <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = questionService.getById(id);
        if(question == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        if(!question.getUserId().equals(loginUser.getId() ) && !userService.isAdmin(loginUser)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        return ResultUtils.success(question);
    }

    /**
     *  查：返回脱敏后的User对象
     * */
    @GetMapping("/get/vo")
    public BaseResponse<QuestionVO> getQuestionVOById(Long id, HttpServletRequest request){
        if(id <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Question question = questionService.getById(id);
        if(question == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        QuestionVO questionVO = questionService.getQuestionVO(question, request);
        return ResultUtils.success(questionVO);
    }

    /**
     *  获取分页后的题目VO
     * */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<QuestionVO>> listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest, HttpServletRequest request){
        long current = questionQueryRequest.getCurrent();
        long pageSize = questionQueryRequest.getPageSize();
        // 限制爬虫
        if(pageSize > 20){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Page<Question> questionPage = questionService.page(new Page<>(current, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        Page<QuestionVO> questionVOPage = questionService.getQuestionVOPage(questionPage, request);
        return ResultUtils.success(questionVOPage);
    }

    /**
     *  用户获取自己的分页后的题目vo
     * */
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<QuestionVO>> listMyQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest,HttpServletRequest request){
        if(questionQueryRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 设置QuestionQueryRequest的用户id
        User loginUser = userService.getLoginUser(request);
        questionQueryRequest.setUserId(loginUser.getId());
        long current = questionQueryRequest.getCurrent();
        long pageSize = questionQueryRequest.getPageSize();
        // 限制爬虫
        if(pageSize > 20){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Page<Question> questionPage = questionService.page(new Page<>(current, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        Page<QuestionVO> questionVOPage = questionService.getQuestionVOPage(questionPage, request);
        return ResultUtils.success(questionVOPage);
    }

    /**
     *  管理员获取分页后的题目列表
     * */
    @PostMapping("/list/page")
    public BaseResponse<Page<Question>> listQuestionPage(@RequestBody QuestionQueryRequest questionQueryRequest, HttpServletRequest request){
        long current = questionQueryRequest.getCurrent();
        long pageSize = questionQueryRequest.getPageSize();
        Page<Question> questionPage = questionService.page(new Page<>(current, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        return ResultUtils.success(questionPage);
    }

    /**
     *  用户对自己的创建的题目进行编辑 editQuestion --- 和 updateQuestion重复
     * */

//    /**
//     *  提交题目作答
//     * */
//    @PostMapping("/question_submit/do")
//    public BaseResponse<Long> doQuestionSubmit(@RequestBody QuestionSubmitAddRequest questionSubmitAddRequest, HttpServletRequest request){
//        if(questionSubmitAddRequest == null || questionSubmitAddRequest.getQuestionId() <= 0){
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        // 登录状态下才能提交题目作答
//        final User loginUser = userService.getLoginUser(request);
//        long questionSubmitId = questionSubmitService.doQuestionSubmit(questionSubmitAddRequest, loginUser);
//        return ResultUtils.success(questionSubmitId);
//    }
//
//    /**
//     * 分页获取题目提交VO列表
//     * */
//    @PostMapping("/question_submit/list/page")
//    public BaseResponse<Page<QuestionSubmitVO>> listQuestionSubmitByPage(@RequestBody QuestionSubmitQueryRequest questionSubmitQueryRequest, HttpServletRequest request){
//        long current = questionSubmitQueryRequest.getCurrent();
//        long size = questionSubmitQueryRequest.getPageSize();
//        Page<QuestionSubmit> questionSubmitPage = questionSubmitService.page(
//                new Page<>(current, size),
//                questionSubmitService.getQueryWrapper(questionSubmitQueryRequest)
//        );
//        final User loginUser = userService.getLoginUser(request);
//        // 脱敏
//        Page<QuestionSubmitVO> questionSubmitVOPage = questionSubmitService.getQuestionSubmitVOPage(questionSubmitPage, loginUser);
//        return ResultUtils.success(questionSubmitVOPage);
//    }
}
